package com.example.demo.zip.service;

import com.example.demo.pdf.PdfDto;
import com.example.demo.pdf.service.PdfService2;
import com.example.demo.zip.test.ZipUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author zjq
 * @version 创建时间：2022-4-6 16:41:00
 */
@Service
public class ProductServiceImpl implements ProductService {

    // zip临时路径
    @Value("${tem-path}")
    private String zipPath;
    @Autowired
    private PdfService2 pdfService2;

    /**
     * ByteArrayOutputStream流的形式生成zip,不推荐使用
     */
    @Override
    public void downLoadFile1(HttpServletRequest req, HttpServletResponse response, List<PdfDto> dto) {

        ZipOutputStream zipStream = null;
        BufferedInputStream bufferStream = null;

        try {
            String desPath = "I:\\java\\test.zip";
            File zipFile = new File(desPath);
            // 构造最终压缩包的输出流
            zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
            ByteArrayOutputStream out = null;

            // 模拟里面有3个文件夹，每个文件夹里5个文件
            for (int i = 0; i < 3; i++) {
                // 1.后半段目录： 2020/03/15
                String directory = "de" + i;
                // 如果目录不存在，则创建
                File dir = new File(directory);
//				if (!dir.exists()) {
//					dir.mkdirs();
//				}
                for (int j = 0; j < 5; j++) {
                    out = pdfService2.fillPdf(dto.get(0));
                    // 压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项，称为条目，就像索引一样
                    ZipEntry zipEntry = new ZipEntry(dir + "/" + "demo" + j + ".pdf");
                    // 定位该压缩条目位置，开始写入文件到压缩包中
                    zipStream.putNextEntry(zipEntry);

                    //方法一：全部一起写入会存在问题
                    //zipStream.write(out.toByteArray());

                    //方法二
                    InputStream fis = byte2InputStream(out.toByteArray());
                    // 使用数组缓冲流，读写多个字节速度变快
                    byte[] bytes = new byte[1024];
                    int len = 0;// 每次读取的有效字节个数
                    while ((len = fis.read(bytes, 0, 1024)) != -1) {
                        zipStream.write(bytes, 0, len);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally { // 关闭流
            try {
                if (null != bufferStream)
                    bufferStream.close();
                if (null != zipStream)
                    zipStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    //多个文件生成zip压缩包
    @Override
    public void zout(HttpServletRequest req, HttpServletResponse response, List<PdfDto> dto, String filename) {

        Long temptime = System.currentTimeMillis();
        String path = zipPath + "tem" + "/" + temptime + "/";
        for (int i = 0; i < 3; i++) {
            // 1.后半段目录： 2021-2022第二学期
            String pathtemp = path + "/";
            //待处理的数据
            List<PdfDto> todel = new ArrayList<>();

            //多线程速度快 ---4为核数
            //ForkJoinPool pool = new ForkJoinPool(Math.min(4, map.size()));
            ForkJoinPool pool = new ForkJoinPool(4);
            ForkJoinTask<?> result = pool.submit(() ->
                    todel.parallelStream().forEach(obj -> {
                        pdfService2.pdfList2(pdfService2.fillData("a", "b"), pathtemp);
                    })
            );
            while (true) {
                if (result.isDone()) {
                    pool.shutdown();
                    break;
                }
            }
        }
        try {
            // 浏览器响应返回
            response.reset();
            // 设置response的header，response为HttpServletResponse接收输出流
            response.setContentType("application/octet-stream");
            String sevenzFileName = "downZip.zip";
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(sevenzFileName, "UTF-8"));
            //待压缩文件夹/文件名
            String srcPath = path;
            ////生成的压缩包名字
            String dest7zFilePath = zipPath + "tem" + "/" + temptime + ".zip";
            // 压缩为zip
            ZipUtil.generateFile(srcPath, "zip", temptime.toString());

            // 将压缩好的zip响应给浏览器
            File file = new File(dest7zFilePath);
            if (null != file && file.isFile()) {
                ServletOutputStream os = response.getOutputStream();
                FileInputStream fis = new FileInputStream(file);
                BufferedInputStream bis = new BufferedInputStream(fis);
                int len = -1;
                // 将源文件写入到输出流
                byte[] buf = new byte[1024];
                while ((len = bis.read(buf)) != -1) {
                    os.write(buf, 0, len);
                }

                bis.close();
                fis.close();
                os.close();

                file.delete();//删除文件
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }


    /**
     * * 文件下载
     *
     * @param request
     * @param response
     * @param filePath 文件路径
     * @param filename 下载时文件名称
     */
    @Override
    public void downLoadFile(HttpServletRequest request, HttpServletResponse response, String filePath,
                             String filename) {
        try {
            File file = new File(filePath);
            // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称 用于浏览器的下载框中自动显示的文件名
            String userAgent = request.getHeader("User-Agent");
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                filename = java.net.URLEncoder.encode(filename, "UTF-8");
            } else {
                filename = new String(filename.getBytes("utf-8"), "iso8859-1");
            }
            response.addHeader("Content-Disposition", "attachment;filename=" + filename);
            // response.setContentType("application/vnd.ms-excel");
            response.setContentType("multipart/form-data");
            byte[] b = new byte[1024];
            int len = 0;
            FileInputStream fs = new FileInputStream(file);
            PrintWriter writer = response.getWriter();
            while ((len = fs.read()) != -1) {
                writer.write(len);
            }
            fs.close();
            writer.close();

            file.delete();//删除文件
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    // byte[]——>inputstream
    public InputStream byte2InputStream(byte[] bytes) {
        return new ByteArrayInputStream(bytes);
    }

}
